package org.batatasframework.support.database.sql.where;

import java.util.List;

import org.batatasframework.support.database.LogicSymbol;
import org.batatasframework.support.database.metadatas.FieldMetadata;
import org.batatasframework.support.database.sql.QueryParameter;
import org.batatasframework.support.database.sql.TableInstance;

import cn.bonoon.kernel.util.Opt;

/**
 * <pre>
 * 位移的计算，只有4种有效的表达式：
 * 等于、不等于、包含、不包含
 * 
 * PS：
 * 	存储的值为：
 * 0011011100011100
 * 
 * 	现在有一个给定的数，如：
 * 0000000000100000
 * 
 * 	要判断存储的值是否有给定的值的位。
 * 注意，给定的值一般是需要2的倍数
 * </pre>
 * @author jackson
 *
 */
public class ShiftQueryFragment extends AbstractQueryFragment<long[]>{

	private final ZeroQueryFragment zeroQueryFragment;
	public ShiftQueryFragment(TableInstance tableSource, FieldMetadata fieldMetadata, Opt opt, long[] value, ZeroQueryFragment zeroQueryFragment) {
		super(tableSource, fieldMetadata, opt, value);
		
		this.zeroQueryFragment = zeroQueryFragment;
	}

	@Override
	public void parse(LogicSymbol logic, StringBuilder sql, List<QueryParameter> paramenters) throws Exception {
		if(opt.getValueCount() == 0){
			zeroQueryFragment.parse(logic, sql, paramenters);
			//这里直接返回，否则后面会添加更多的查询条件进来的
			
			/* 一般不会进这里的 */
			return;
		}
		
		//如果是某一个操作，但没有参数的，则不使用这个查询条件
		if(null == value || value.length == 0) return;

		if(opt == Opt.EQ){
			
			//x.col&1<<?>0
			sql.append(logic.getValue()).append(columnName)
				.append("&1<<").append(value[0]).append(">0");
		}else if(opt == Opt.NE){
			
			//x.col&1<<1=0
			sql.append(logic.getValue()).append("(")
				.append(columnName).append(" is null or ")
				.append(columnName).append("&1<<")
				.append(value[0]).append("=0)");
			
		}else if(opt == Opt.IN){
			
			sql.append(logic.getValue()).append("(")
				.append(columnName).append("&1<<")
				.append(value[0]).append(">0");
			
			for(int i = 1; i < value.length; i++){
				sql.append(" or ").append(columnName)
					.append("&1<<").append(value[i]).append(">0");
			}
			sql.append(")");
		}else if(opt == Opt.NI){
			
			sql.append(logic.getValue()).append("(")
				.append(columnName).append(" is null or not(")
				.append(columnName).append("&1<<")
				.append(value[0]).append(">0");
			
			for(int i = 1; i < value.length; i++){
				
				sql.append(" or ").append(columnName)
					.append("&1<<").append(value[i]).append(">0");
				
			}
			sql.append("))");
		}
		
		//忽略掉其他的查询逻辑类型
	}

}
